//包含LUA的头文件，用来支持脚本
#include <stdio.h>
#include "lib/lua-5.3.1/lua.h"  
#include "lib/lua-5.3.1/lualib.h"  
#include "lib/lua-5.3.1/lauxlib.h"   

#include "lib/includes.h"
#include "cputest.h"

extern char IPADDR1[40];//服务器IP地址，读卡用
extern int  PORT1;      //服务器IP端口
//#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))

lua_State* L;  
int add(lua_State* L);  
  
int add(lua_State* L)  
{  
    //从L栈中取出索引为1的数值，并检查  
    int x = luaL_checkinteger(L,1);  
    //从L栈中取出索引为2的数值，并检查  
    int y = luaL_checkinteger(L,2);  
    printf("sum:%d\n",x+y);  
    //将函数的结果压入栈中。如果有多个返回值，可以在这里多次压入栈中。
    lua_pushnumber(L,x + y); 
    return 1;  
}  
//为了说明这些函数的用法，这里有一个有用的帮助函数，它dump整个堆栈的内容：
static void stackDump (lua_State *L) 
{
	int i;
	int top = lua_gettop(L);
	for (i = 1; i <= top; i++) 
	{
		int t = lua_type(L, i);
		switch (t) 
		{
			case LUA_TSTRING:
			printf("%s",lua_tostring(L, i));
			break;

			case LUA_TBOOLEAN:
			printf(lua_toboolean(L, i) ? "true" : "false");
			break;

			case LUA_TNUMBER:
			printf("%g", lua_tonumber(L, i));
			break;

			default:
			printf("%s", lua_typename(L, t));
			break;

	    }
	    printf(" ");
	}
	printf("\n");
}
int testDump(void) 
{
	L = luaL_newstate();  //创建lua的栈 
	luaL_openlibs(L);

	lua_pushboolean(L, 1);
	lua_pushnumber(L, 10);

	lua_pushnil(L); lua_pushstring(L, "hello");

	stackDump(L);

	lua_pushvalue(L, -4);

	stackDump(L);

	lua_replace(L, 3);

	stackDump(L);

	lua_settop(L, 6);

	stackDump(L);

	lua_remove(L, -3);

	stackDump(L);

	lua_settop(L, -5);

	stackDump(L);

	lua_close(L);

    return 0;
}

int LConnect(lua_State* L)
{
    int ret = 0;
    printf("Connecting...\n");
    printf("ServerIP:%s,Port:%d\n", IPADDR1,PORT1);
    ret = Connect(IPADDR1,PORT1);
    if(ret)
       printf("connect fail!\n");
    else
       printf("connect ok!\n");
    lua_pushnumber(L,ret); 
    return 1;
}
int LSelectAID(lua_State* L)
{
 	int ret = 0;
 	size_t le = 0;
 	unsigned char buf[520];
	
	memset(buf, 0, 520);
 	//从L栈中取出索引为1的数值，并检查  
    const char * aid = luaL_checklstring(L,1,&le);
    //printf("aid is %s,le is %d\n",aid,le);  
    //从L栈中取出索引为2的数值，并检查  
    int len = luaL_checkinteger(L,2); 
    int ich = luaL_checkinteger(L,3); 

    ret = ICF_SelectAID( aid, len, ich );
    HexToStr(gpRcvBuffer,Grcv_Len,(char*)buf);
    lua_pushinteger(L,ret); 
    lua_pushlstring(L,(char*)buf,strlen((char*)buf));
    return 2;

}

int LSelectSFI(lua_State* L)
{
 	int ret = 0;
 	size_t le = 0;
 	unsigned char buf[520];
	
	memset(buf, 0, 520);
 	//从L栈中取出索引为1的数值，并检查  
    const char * sfi = luaL_checklstring(L,1,&le);
    //printf("aid is %s,le is %d\n",aid,le);  
    //从L栈中取出索引为2的数值，并检查  
    int ich = luaL_checkinteger(L,2); 

    ret = ICF_SelectSFI( sfi, ich );
    HexToStr(gpRcvBuffer,Grcv_Len,(char*)buf);
    lua_pushinteger(L,ret); 
    lua_pushlstring(L,(char*)buf,strlen((char*)buf));
    return 2;

}
int LReadBinaryFile( lua_State* L )
{
	int ret = 0;
	unsigned char buf[520];
	
	memset(buf, 0, 520);
 	//从L栈中取出索引为1的数值，并检查  
    int sfi =  luaL_checkinteger(L,1); 
    int oft =  luaL_checkinteger(L,2);
    int rlen = luaL_checkinteger(L,3);
    int ich =  luaL_checkinteger(L,4); 

    ret = ICF_ReadBinaryFile(sfi,oft,rlen,ich);

    HexToStr(gpRcvBuffer,Grcv_Len,(char*)buf);
    lua_pushinteger(L,ret); 
    lua_pushlstring(L,(char*)buf,strlen((char*)buf));

    //stackDump(L);
    return 2;
}

int LGetBalanceEP( lua_State* L )
{
	int ret = 0;
	unsigned int ep;
    unsigned char buf[520];
	
	memset(buf, 0, 520);

    //int tt =  luaL_checkinteger(L,1); 

    //printf("tt is:%d\n",tt);

    ret = ICF_GetBalanceEP(&ep,0);

    HexToStr(gpRcvBuffer,Grcv_Len,(char*)buf);
    lua_pushinteger(L,ret); 
    lua_pushlstring(L,(char*)buf,strlen((char*)buf));

    //stackDump(L);
    return 2;
}

int LAPDU_Exchange(lua_State* L)
{
	int ret = 0;
 	size_t le = 0;
 	unsigned char buf[520];
	
	memset(buf, 0, 520);
 	//从L栈中取出索引为1的数值，并检查  
    const char * cmd = luaL_checklstring(L,1,&le);
    //printf("cmd is %s,le is %d\n",aid,le);  
    //从L栈中取出索引为2的数值，并检查  
    int ich = luaL_checkinteger(L,2); 

    StrToHex( (char*)cmd, le, gCmdBuffer );

    ret = ICC_APDU_Exchange( ich, gCmdBuffer, le/2, gpRcvBuffer, &Grcv_Len, ICC_APDU_Rcv_MAXBUF );
    if( Grcv_Len < 2)
	{ return 1;}

    ret = ( ( gpRcvBuffer[ Grcv_Len - 2 ] << 8 ) | gpRcvBuffer[ Grcv_Len - 1 ] );

    HexToStr(gpRcvBuffer,Grcv_Len,(char*)buf);
    lua_pushinteger(L,ret); 
    lua_pushlstring(L,(char*)buf,strlen((char*)buf));
    return 2;
}

int lua_test( void )  
{  
    //初始化全局L  
    L = luaL_newstate();  //创建lua的栈 
    //打开库  
    luaL_openlibs(L);  
    //把函数压入栈中  
    lua_pushcfunction(L, add);  
    //设置全局ADD  
    lua_setglobal(L, "ADD");  
    //lua_register(L,"ADD",add);
    lua_pushcfunction(L, LConnect);  
    //设置全局ADD  
    lua_setglobal(L, "CONNECT"); 

    lua_register(L,"SelectAID",LSelectAID); 
    lua_register(L,"SelectSFI",LSelectSFI); 
    lua_register(L,"ReadBinFile", LReadBinaryFile);
    lua_register(L,"GetBalanceEP",LGetBalanceEP);  
    lua_register(L,"APDU", LAPDU_Exchange);  

    //加载我们的lua脚本文件  
    if (luaL_loadfile(L,"mylua.lua"))  //载入lua脚本，是通过fopen打开的，
    {  
        printf("error\n");  
    }  
    //安全检查  
    lua_pcall(L,0,0,0); //这个函数会执行lua脚本 
    //push进lua函数  
   // lua_getglobal(L, "mylua1"); 
   // lua_pcall(L,0,0,0);     
    printf("hello my lua,end\n"); 
    lua_close(L); //关闭lua的栈  

   // testDump(); 
    return 0;  
} 

